{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Grove Light sensor module\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Aim\n",
    "\n",
    "* This notebook illustrates how to use available APIs for the Grove Light sensor module on PYNQ-Z2 PMOD and Arduino interfaces.\n",
    "\n",
    "\n",
    "## References\n",
    "* [Grove Light sensor](https://www.seeedstudio.com/Grove-Light-Sensor-v1-2-LS06-S-phototransistor.html) \n",
    "* [Grove I2C ADC](https://www.seeedstudio.com/Grove-I2C-ADC.html) \n",
    "* [PYNQ Grove Adapter](https://store.digilentinc.com/pynq-grove-system-add-on-board/)\n",
    "* [Grove Base Shield V2.0](https://www.seeedstudio.com/Base-Shield-V2.html)   \n",
    "\n",
    "## Last revised\n",
    "* 01 April 2021\n",
    "    + Initial version\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load _base_ Overlay"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-box alert-info\">\n",
    "Note that we load the base bitstream only once to use Grove module with PYNQ Grove Adapter and SEEED Grove Base Shield V2.0<br>\n",
    "Please make sure you run the following cell before running either of the interfaces \n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "module 'pynq' has no attribute 'ps'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-7-3ec93208ea83>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mpynq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moverlays\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbase\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mBaseOverlay\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mpynq_peripherals\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mArduinoSEEEDGroveAdapter\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mPmodGroveAdapter\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mbase\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mBaseOverlay\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'base.bit'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pynq/__init__.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     45\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mbuffer\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mallocate\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     46\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mpl_server\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mDevice\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 47\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mlib\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     49\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pynq/lib/__init__.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     73\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m\u001b[0mlogictools\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mFSMGenerator\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     74\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 75\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mvideo\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     76\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0maudio\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     77\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mdma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pynq/lib/video/__init__.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     38\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mclocks\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     39\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mpynq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCPU_ARCH\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mpynq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mZYNQ_ARCH\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     41\u001b[0m     \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mdvi\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     42\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mpynq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCPU_ARCH\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mpynq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mps\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mZU_ARCH\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mAttributeError\u001b[0m: module 'pynq' has no attribute 'ps'"
     ]
    }
   ],
   "source": [
    "from pynq.overlays.base import BaseOverlay\n",
    "from pynq_peripherals import ArduinoSEEEDGroveAdapter, PmodGroveAdapter\n",
    "base = BaseOverlay('base.bit')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Using Grove Light with Grove Base Shield V2.0 (Arduino)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Library compilation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-box alert-warning\"><ul>\n",
    "    <h4 class=\"alert-heading\">Make Physical Connections </h4>\n",
    "    <li>Insert the SEEED Grove Base Shield into the Arduino connector on the board. Connect the Grove Light sensor to A1 connector of the Grove Base Shield.</li>\n",
    "</ul>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adapter configuration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "adapter = ArduinoSEEEDGroveAdapter(base.ARDUINO, A1='grove_light')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define device object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "light_sensor = adapter.A1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reading from the Grove Light sensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('percentage: %.2f%%' % light_sensor.get_intensity())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Taking multiple samples at a desired interval and plotting\n",
    "Set numberOfSamples and delayInSeconds to desired values. Vary light intensity manually. Print samples and then plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "from time import sleep\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "numberOfSamples = 20\n",
    "delayInSeconds = 1\n",
    "light = np.zeros(numberOfSamples)\n",
    "\n",
    "for i in range(numberOfSamples):\n",
    "    light[i]=light_sensor.get_intensity()\n",
    "    sleep(delayInSeconds)\n",
    "    \n",
    "plt.plot(range(numberOfSamples), light, 'ro')\n",
    "plt.title('Light Intensity in Percentage')\n",
    "plt.axis([0, int(numberOfSamples), 0, 100])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## Using Grove Light sensor with Grove ADC (Arduino)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-box alert-warning\"><ul>\n",
    "    <h4 class=\"alert-heading\">Make Physical Connections </h4>\n",
    "    <li>Insert the Grove Base Shield into the Arduino connector on the board. Connect the grove_adc module to one of the connectors labeled I2C.</li>\n",
    "    <li>Connect the Grove Light sensor to the grove_adc module.</li></ul>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adapter configuration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "adapter = ArduinoSEEEDGroveAdapter(base.ARDUINO, I2C='grove_light')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define device object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "light_sensor = adapter.I2C"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reading from the Grove Light sensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('percentage: %.2f%%' % light_sensor.get_intensity())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Taking multiple samples at a desired interval and plotting\n",
    "Set numberOfSamples and delayInSeconds to desired values. Vary light intensity manually. Print samples and then plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "from time import sleep\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "numberOfSamples = 20\n",
    "delayInSeconds = 1\n",
    "light = np.zeros(numberOfSamples)\n",
    "\n",
    "for i in range(numberOfSamples):\n",
    "    light[i]=light_sensor.get_intensity()\n",
    "    sleep(delayInSeconds)\n",
    "    \n",
    "plt.plot(range(numberOfSamples), light, 'ro')\n",
    "plt.title('Light Intensity in Percentage')\n",
    "plt.axis([0, int(numberOfSamples), 0, 100])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## Using Grove Light sensor with PYNQ Grove Adapter (PMOD)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-box alert-warning\"><ul>\n",
    "    <h4 class=\"alert-heading\">Make Physical Connections </h4>\n",
    "    <li>Connect the PYNQ Grove Adapter to PMODB connector. Connect the grove_adc module to the G3 connector of the Adapter.</li>\n",
    "    <li>Connect the Grove Light sensor to the grove_adc module.</li></ul>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adapter configuration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "adapter = PmodGroveAdapter(base.PMODB, G3='grove_light')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define device object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "light_sensor = adapter.G3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reading from the Grove Light sensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('percentage: %.2f%%' % light_sensor.get_intensity())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Taking multiple samples at a desired interval and plotting\n",
    "Set numberOfSamples and delayInSeconds to desired values. Vary light intensity manually. Print samples and then plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "from time import sleep\n",
    "import numpy as np\n",
    "import math\n",
    "\n",
    "numberOfSamples = 20\n",
    "delayInSeconds = 1\n",
    "light = np.zeros(numberOfSamples)\n",
    "\n",
    "for i in range(numberOfSamples):\n",
    "    light[i]=light_sensor.get_intensity()\n",
    "    sleep(delayInSeconds)\n",
    "    \n",
    "plt.plot(range(numberOfSamples), light, 'ro')\n",
    "plt.title('Light Intensity in Percentage')\n",
    "plt.axis([0, int(numberOfSamples), 0, 100])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copyright (C) 2021 Xilinx, Inc\n",
    "\n",
    "SPDX-License-Identifier: BSD-3-Clause"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
